﻿using log4net;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Modules.ActionRun;
using Modules.Monitoring;
using Modules.SysDebug;
using Modules.Units;
using Prism.Ioc;
using Prism.Modularity;
using Sorting.App.Models;
using Sorting.App.Modules.ModuleName;
using Sorting.App.Services;
using Sorting.App.Views;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using FurionApp = Furion.App;


namespace Sorting.App
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        /// <summary>
        /// 应用启动时注册
        /// </summary>
        /// <param name="containerRegistry"></param>
        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            
            containerRegistry.RegisterSingleton<LoginService, LoginService>();
            containerRegistry.RegisterSingleton<HisTaskLogService, HisTaskLogService>();
        }


        /// <summary>
        /// 应用启动时注册模块
        /// </summary>
        /// <param name="moduleCatalog"></param>
        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {

            //主界面模块
            moduleCatalog.AddModule<TaskManModule>();

            //系统维护整体模块
            moduleCatalog.AddModule<SysDebugModule>();

            //设备主要状态监控模块
            moduleCatalog.AddModule<MonitoringModule>();

            
        }




        /// <summary>
        /// 配置（只读）
        /// </summary>
        public static IConfiguration Configuration { get; private set; }
        private readonly ILog _log = LogManager.GetLogger(typeof(App));
        private readonly IHost _host;
        public App()
        {
            Configuration = new ConfigurationBuilder()
                .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true, Optional = true })
                //.AddJsonFile("Setting/stockerconfig.json", optional: true, reloadOnChange: true)
                .Build();

            _host = CreateHostBuilder().Build();




            AppsettingUnits.Appseeting = FurionApp.GetConfig<CommonConfigOptions>("CommonConfig", true);
            AppsettingUnits.rabbitMq = FurionApp.GetConfig<RabbitMqOptionDto>("RabbitOptions", true);

            GetToken();
            //指定Log4配置文件
            log4net.Config.XmlConfigurator.Configure(
                new FileInfo(System.Environment.CurrentDirectory + "/log4net.config")
                );




            //UI线程未捕获异常处理事件
            this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            //非UI线程未捕获异常处理事件
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


            Current.Startup += Current_Startup;

            this.Startup += App_Startup;
        }

        System.Threading.Mutex mutex;
        private void App_Startup(object sender, StartupEventArgs e)
        {
            bool ret;
            mutex = new System.Threading.Mutex(true, "SortingApp", out ret);

            if (!ret)
            {
                MessageBox.Show("已有一个客户端正在运行,请先结束原来客户端!");
                Environment.Exit(0);
            }


            CultureInfo culture = CultureInfo.CreateSpecificCulture("zh-CN");

            // The following line provides localization for the application's user interface. 
            Thread.CurrentThread.CurrentUICulture = culture;

            // The following line provides localization for data formats. 
            Thread.CurrentThread.CurrentCulture = culture;

            // Set this culture as the default culture for all threads in this application. 
            CultureInfo.DefaultThreadCurrentCulture = culture;
            CultureInfo.DefaultThreadCurrentUICulture = culture;
        }

        private void Current_Startup(object sender, StartupEventArgs e)
        {
            _host.StartAsync();

            IServiceProvider services = _host.Services;

        }

        private async void GetToken()
        {
            LoginService _loginService = new LoginService();

            //var res = await _loginService.Login("admin", "admin");

            //AppsettingUnits.Token = res.data.Token;

        }


        #region 全局异常处理
        void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            try
            {
                e.Handled = true; //把 Handled 属性设为true，表示此异常已处理，程序可以继续运行，不会强制退出      
                Trace.WriteLine("异常:" + e.Exception.Message);
                _log.Error(e.Exception);

            }
            catch (Exception ex)
            {
                //此时程序出现严重异常，将强制结束退出
                Trace.WriteLine("发生致命错误");
                _log.Error("发生致命错误"+ex);
            }

        }

        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            StringBuilder sbEx = new StringBuilder();
            if (e.IsTerminating)
            {
                sbEx.Append("非UI线程发生致命错误");
            }
            sbEx.Append("非UI线程异常：");
            if (e.ExceptionObject is Exception)
            {
                sbEx.Append(((Exception)e.ExceptionObject).Message);
            }
            else
            {
                sbEx.Append(e.ExceptionObject);
            }
            Trace.WriteLine(sbEx.ToString());
            _log.Error(sbEx.ToString());
        }

        void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            //task线程内未处理捕获
            Trace.WriteLine("Task线程异常：" + e.Exception.Message);
            _log.Error("Task线程异常：" + e.Exception.Message);
            e.SetObserved();//设置该异常已察觉（这样处理后就不会引起程序崩溃）
        }

        #endregion



        /// <summary>
        /// 注入系统配置
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static IHostBuilder CreateHostBuilder(string[] args = null)
        {
            return Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.Inject();
                    })
                .ConfigureServices((context, services) =>
                {
                  



                    services.AddRemoteRequest();

                    services.AddEventBus();


                });
        }


    }
}
